package management

import (
	"context"
	"encoding/json"
	"net/http"
	"strconv"
	"time"

	"github.com/gorilla/mux"
	"github.com/jsrccb/nachuan/common"
	"go.mongodb.org/mongo-driver/bson"
	"go.mongodb.org/mongo-driver/mongo"
	"go.mongodb.org/mongo-driver/mongo/options"
)

func initSaleChannelApi(r *mux.Router) {
	s := r.PathPrefix("/salechannel").Subrouter()
	// s.HandleFunc("/list", UserListHandler)
	s.HandleFunc("/updsave", handleSaveSaleChannel)
	s.HandleFunc("/saverolesalechannel", handleSaveRoleSaleChannel)
	//请求/rolelimits/querybyrolename?rolename=xxx
	s.HandleFunc("/queryall", handleSaleChannelQuery)
	s.HandleFunc("/querysalechannelbyrolename", handleSaleChannelQueryByName)

	sysconfig := r.PathPrefix("/sysconfig").Subrouter()
	sysconfig.HandleFunc("/updsave", handleSaveSysConfig)
	sysconfig.HandleFunc("/query", handleQueryConfigAllBySkip)
	sysconfig.HandleFunc("/delbysysconfigbyname", handleDelSysConfig)
	sysconfig.HandleFunc("/querysysconfigbyname", handleSysConfigQueryByName)

}

type SaleChannelMgr struct {
	client              *mongo.Client
	SaleChannelColl     *mongo.Collection
	RoleSaleChannelColl *mongo.Collection
	SysConfigColl       *mongo.Collection
}

var (
	G_SaleChannelMgr *SaleChannelMgr
)

func InitSaleChannelMgr() (err error) {

	G_SaleChannelMgr = &SaleChannelMgr{
		client:              G_MongoMgr.client,
		SaleChannelColl:     G_MongoMgr.MongdbConnect.Collection("salechannel"),
		RoleSaleChannelColl: G_MongoMgr.MongdbConnect.Collection("rolesalechannel"),
		SysConfigColl:       G_MongoMgr.MongdbConnect.Collection("sysconfig"),
	}

	return
}

func (salechannelmgr *SaleChannelMgr) DelSysConfig(sysconfigname string) (err error) {

	_, err = salechannelmgr.SysConfigColl.DeleteOne(context.TODO(), bson.M{"configName": sysconfigname})
	// if doccount > 0 {
	// 	_, err = salechannelmgr.SysConfigColl.UpdateOne(context.TODO(), bson.M{"configName": sysconfig.ConfigName}, bson.M{"$set": sysconfig})
	// } else {
	// 	salechannelmgr.SysConfigColl.InsertOne(context.TODO(), sysconfig)
	// }
	return
}

func (salechannelmgr *SaleChannelMgr) SaveSysConfig(sysconfig *common.SysConfig) (err error) {

	var (
		doccount int64
	)
	sysconfig.CreateTime = common.BuildTimeNowStr()

	doccount, err = salechannelmgr.SysConfigColl.CountDocuments(context.TODO(), bson.M{"configName": sysconfig.ConfigName})

	if doccount > 0 {
		_, err = salechannelmgr.SysConfigColl.UpdateOne(context.TODO(), bson.M{"configName": sysconfig.ConfigName}, bson.M{"$set": sysconfig})
	} else {
		salechannelmgr.SysConfigColl.InsertOne(context.TODO(), sysconfig)
	}

	return
}

func (salechannelmgr *SaleChannelMgr) SaveSaleChannel(salechannel *common.SaleChannel) (err error) {

	var (
		doccount int64
	)
	salechannel.CreateTime = common.BuildTimeNowStr()
	doccount, err = salechannelmgr.SaleChannelColl.CountDocuments(context.TODO(), bson.M{"channelName": salechannel.ChannelName})
	if doccount > 0 {
		_, err = salechannelmgr.SaleChannelColl.UpdateOne(context.TODO(), bson.M{"channelName": salechannel.ChannelName}, bson.M{"$set": salechannel})
	} else {
		salechannelmgr.SaleChannelColl.InsertOne(context.TODO(), salechannel)
	}

	return
}

func (salechannelmgr *SaleChannelMgr) DelRoleSaleChannel(rolename string) (err error) {

	_, err = salechannelmgr.SaleChannelColl.DeleteOne(context.TODO(), bson.M{"roleName": rolename})

	return
}

func (salechannelmgr *SaleChannelMgr) QueryAllSaleChannel() (salechannels []*common.SaleChannel, err error) {

	var (
		cursor      *mongo.Cursor
		ctx         context.Context
		salechannel *common.SaleChannel
	)
	if cursor, err = salechannelmgr.SaleChannelColl.Find(ctx, bson.M{}); err != nil {
		return
	}
	defer cursor.Close(ctx)

	//反序列化到bson
	for cursor.Next(ctx) {
		salechannel = &common.SaleChannel{}
		if err = cursor.Decode(salechannel); err != nil {
			continue
		}
		// fmt.Println(jobLog)
		salechannels = append(salechannels, salechannel)
	}
	return
}

func (salechannelmgr *SaleChannelMgr) QuerySaleChannelByRoleName(rolename string) (rolesalechannel *common.RoleSaleChannel, err error) {

	var (
		ctx context.Context
	)
	err = salechannelmgr.RoleSaleChannelColl.FindOne(ctx, bson.M{"roleName": rolename}).Decode(&rolesalechannel)

	return
}

func (salechannelmgr *SaleChannelMgr) QuerySysConfigByName(configname string) (sysconfig *common.SysConfig, err error) {

	var (
		ctx context.Context
	)
	err = salechannelmgr.SysConfigColl.FindOne(ctx, bson.M{"configName": configname}).Decode(&sysconfig)

	return
}

func (salechannelmgr *SaleChannelMgr) SaveRoleSaleChannel(rolesalechannel *common.RoleSaleChannel) (err error) {
	var (
		doccount int64
	)
	rolesalechannel.CreateTime = common.BuildTimeNowStr()

	doccount, err = salechannelmgr.RoleSaleChannelColl.CountDocuments(context.TODO(), bson.M{"roleName": rolesalechannel.RoleName})

	if doccount > 0 {
		_, err = salechannelmgr.RoleSaleChannelColl.UpdateOne(context.TODO(), bson.M{"roleName": rolesalechannel.RoleName}, bson.M{"$set": rolesalechannel})
	} else {
		_, err = salechannelmgr.RoleSaleChannelColl.InsertOne(context.TODO(), rolesalechannel)
	}
	return
}

func handleSaleChannelQuery(resp http.ResponseWriter, req *http.Request) {
	var (
		err          error
		bytes        []byte
		salechannels []*common.SaleChannel
		// rolelimit     *common.RoleLimits
	)
	if err = req.ParseForm(); err != nil {
		goto ERR
	}
	// channelinfostr = req.PostForm.Get("channelinfo")

	// if err = json.Unmarshal([]byte(channelinfostr), &channelinfo); err != nil {
	// 	goto ERR
	// }
	if salechannels, err = G_SaleChannelMgr.QueryAllSaleChannel(); err != nil {
		goto ERR
	}
	if bytes, err = common.BuildResponse(0, "success", salechannels); err == nil {
		resp.Write(bytes)
	}
	return
ERR:
	if bytes, err = common.BuildResponse(-1, err.Error(), nil); err == nil {
		resp.Write(bytes)
	}
}

func handleSaleChannelQueryByName(resp http.ResponseWriter, req *http.Request) {

	var (
		err             error
		bytes           []byte
		rolesalechannel *common.RoleSaleChannel
		rolename        string
	)

	query := req.URL.Query()
	rolename = query.Get("rolename")

	// if err = json.Unmarshal([]byte(channelinfostr), &channelinfo); err != nil {
	// 	goto ERR
	// }
	if rolesalechannel, err = G_SaleChannelMgr.QuerySaleChannelByRoleName(rolename); err != nil {
		goto ERR
	}
	if bytes, err = common.BuildResponse(0, "success", rolesalechannel); err == nil {
		resp.Write(bytes)
	}
	return
ERR:
	if bytes, err = common.BuildResponse(-1, err.Error(), nil); err == nil {
		resp.Write(bytes)
	}
}

func handleSysConfigQueryByName(resp http.ResponseWriter, req *http.Request) {

	var (
		err        error
		bytes      []byte
		sysconfig  *common.SysConfig
		configname string
	)

	query := req.URL.Query()
	configname = query.Get("configname")

	// if err = json.Unmarshal([]byte(channelinfostr), &channelinfo); err != nil {
	// 	goto ERR
	// }
	if sysconfig, err = G_SaleChannelMgr.QuerySysConfigByName(configname); err != nil {
		goto ERR
	}
	if bytes, err = common.BuildResponse(0, "success", sysconfig); err == nil {
		resp.Write(bytes)
	}
	return
ERR:
	if bytes, err = common.BuildResponse(-1, err.Error(), nil); err == nil {
		resp.Write(bytes)
	}
}

func handleSaveRoleSaleChannel(resp http.ResponseWriter, req *http.Request) {
	var (
		err                error
		bytes              []byte
		rolechannelinfo    *common.RoleSaleChannel
		rolechannelinfostr string
		// rolelimit     *common.RoleLimits
	)
	if err = req.ParseForm(); err != nil {
		goto ERR
	}
	rolechannelinfostr = req.PostForm.Get("rolechannelinfo")

	if err = json.Unmarshal([]byte(rolechannelinfostr), &rolechannelinfo); err != nil {
		goto ERR
	}

	if err = G_SaleChannelMgr.SaveRoleSaleChannel(rolechannelinfo); err != nil {
		goto ERR
	}
	if bytes, err = common.BuildResponse(0, "success", "维护角色营销渠道成功"); err == nil {
		resp.Write(bytes)
	}
	return
ERR:
	if bytes, err = common.BuildResponse(-1, err.Error(), nil); err == nil {
		resp.Write(bytes)
	}
}

func handleSaveSaleChannel(resp http.ResponseWriter, req *http.Request) {
	var (
		err            error
		bytes          []byte
		channelinfo    *common.SaleChannel
		channelinfostr string
		// rolelimit     *common.RoleLimits
	)
	if err = req.ParseForm(); err != nil {
		goto ERR
	}
	channelinfostr = req.PostForm.Get("channelinfo")

	if err = json.Unmarshal([]byte(channelinfostr), &channelinfo); err != nil {
		goto ERR
	}
	if err = G_SaleChannelMgr.SaveSaleChannel(channelinfo); err != nil {
		goto ERR
	}
	if bytes, err = common.BuildResponse(0, "success", "新增营销渠道成功"); err == nil {
		resp.Write(bytes)
	}
	return
ERR:
	if bytes, err = common.BuildResponse(-1, err.Error(), nil); err == nil {
		resp.Write(bytes)
	}
}

func handleSaveSysConfig(resp http.ResponseWriter, req *http.Request) {
	var (
		err           error
		bytes         []byte
		configinfo    *common.SysConfig
		configinfostr string
		// rolelimit     *common.RoleLimits
	)
	if err = req.ParseForm(); err != nil {
		goto ERR
	}
	configinfostr = req.PostForm.Get("configinfo")

	if err = json.Unmarshal([]byte(configinfostr), &configinfo); err != nil {
		goto ERR
	}
	if err = G_SaleChannelMgr.SaveSysConfig(configinfo); err != nil {
		goto ERR
	}
	if bytes, err = common.BuildResponse(0, "success", "新增系统配置成功"); err == nil {
		resp.Write(bytes)
	}
	return
ERR:
	if bytes, err = common.BuildResponse(-1, err.Error(), nil); err == nil {
		resp.Write(bytes)
	}
}

func handleDelSysConfig(resp http.ResponseWriter, req *http.Request) {

	var (
		configinfostr string
		err           error
		bytes         []byte
	)

	if err = req.ParseForm(); err != nil {
		goto ERR
	}

	// configinfostr = req.PostFormValue("phoneno")
	configinfostr = req.PostForm.Get("configname")
	// fmt.Println(configinfostr)

	G_SaleChannelMgr.DelSysConfig(configinfostr)

	if bytes, err := common.BuildResponse(0, "success", "配置删除成功"); err == nil {
		resp.Write(bytes)
	}
	return
ERR:
	if bytes, err = common.BuildResponse(-1, err.Error(), nil); err == nil {
		resp.Write(bytes)
	}
}

func handleQueryConfigAllBySkip(resp http.ResponseWriter, req *http.Request) {
	var (
		err         error
		bytes       []byte
		sysconfig   []*common.SysConfig
		skipParam   string
		limitParam  string
		skip        int
		limit       int
		configcount int64
	)

	query := req.URL.Query()
	skipParam = query.Get("skip")
	limitParam = query.Get("limit")
	if skip, err = strconv.Atoi(skipParam); err != nil {
		skip = 0
	}

	if limit, err = strconv.Atoi(limitParam); err != nil {
		limit = 100
	}

	sysconfig, _ = G_SaleChannelMgr.ListConfig(int64(skip), int64(limit))
	configcount, _ = G_SaleChannelMgr.CountConfig()

	configmap := make(map[string]interface{})
	configmap["configcount"] = configcount
	configmap["configinfo"] = sysconfig

	if sysconfig != nil {
		if bytes, err = common.BuildResponse(0, "success", configmap); err == nil {
			resp.Write(bytes)
		}
	} else {
		if bytes, err = common.BuildResponse(-1, "error", "无可用配置"); err == nil {
			resp.Write(bytes)
		}
	}
	return
}

func (salechannelmgr *SaleChannelMgr) ListConfig(skip int64, limit int64) (sysconfig []*common.SysConfig, err error) {

	var (
		cursor  *mongo.Cursor
		findopt *options.FindOptions
		ctx     context.Context
		// userInfo *common.
		config *common.SysConfig
	)

	//预防查询不到结果返回nil，这样返回是空数组
	sysconfig = make([]*common.SysConfig, 0)

	ctx, _ = context.WithTimeout(context.Background(), 10*time.Second)

	if limit > 0 && skip >= 0 {
		findopt = &options.FindOptions{}
		findopt.SetLimit(limit)
		findopt.SetSkip(limit * skip)

	} else {
		return
	}
	if cursor, err = salechannelmgr.SysConfigColl.Find(ctx, bson.M{}, findopt); err != nil {
		return
	}
	// fmt.Print(cursor)
	defer cursor.Close(ctx)

	//反序列化到bson
	for cursor.Next(ctx) {
		config = &common.SysConfig{}
		if err = cursor.Decode(config); err != nil {
			continue
		}
		// fmt.Println(jobLog)
		sysconfig = append(sysconfig, config)
	}
	return
}

func (salechannelmgr *SaleChannelMgr) CountConfig() (configcount int64, err error) {
	var (
		ctx context.Context
	)
	ctx, _ = context.WithTimeout(context.Background(), 15*time.Second)

	configcount, err = salechannelmgr.SysConfigColl.CountDocuments(ctx, bson.M{})
	return
}
